package api

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"gitlab.com/go-course-project/go17/book/config"
	"gitlab.com/go-course-project/go17/book/controller"
	"gitlab.com/go-course-project/go17/book/model"
	"gitlab.com/go-course-project/go17/book/response"
	"gorm.io/gorm"
)

// 构造函数, 用户初始化这个结构体
func NewBookHandler() *BookApiHandler {
	return &BookApiHandler{
		db:  config.Get().MySQL.DB(),
		svc: controller.NewBookController(),
	}
}

// 面向对象
// BookApiHandler 他来实现接口的功能
type BookApiHandler struct {
	db *gorm.DB

	svc *controller.BookController
}

// 提供注册功能, 提供一个Group
// book := server.Group("/api/books")
func (h *BookApiHandler) Registry(r *gin.Engine) {
	book := r.Group("/api/books")
	book.POST("", h.CreateBook)
	book.GET("", h.ListBook)
	book.GET("/:isbn", h.GetBook)
	book.PUT("/:isbn", h.UpdateBook)
	book.DELETE("/:isbn", h.DeleteBook)
}

// 配置业务路有, Book类型的资源的 一套简单的CRUD
// 创建Book -> Book
// POST, Body
func (h *BookApiHandler) CreateBook(ctx *gin.Context) {
	// 获取Book用户传达的参数
	req := new(model.BookSpec)
	if err := ctx.ShouldBindJSON(req); err != nil {
		response.Failed(ctx, err)
		return
	}

	ins, err := h.svc.CreateBook(ctx.Request.Context(), req)
	if err != nil {
		response.Failed(ctx, err)
		return
	}

	response.Success(ctx, ins)
}

// 查询Book列表 -> []*Book
// SELECT * FROM `books`
func (h *BookApiHandler) ListBook(ctx *gin.Context) {
	var books []model.Book
	if err := h.db.Find(&books).Error; err != nil {
		response.Failed(ctx, err)
		return
	}
	ctx.JSON(http.StatusOK, books)
}

// 查询Book详情
func (h *BookApiHandler) GetBook(ctx *gin.Context) {
	strId := ctx.Param("isbn")
	id, err := strconv.ParseInt(strId, 10, 64)
	if err != nil {
		response.Failed(ctx, err)
		return
	}

	// 传递HTTP请求的上下文
	ins, err := h.svc.GetBook(ctx.Request.Context(), &controller.GetBookRequest{
		Isbn: id,
	})
	if err != nil {
		response.Failed(ctx, err)
		return
	}

	ctx.JSON(http.StatusOK, ins)
}

// 更新Book
func (h *BookApiHandler) UpdateBook(ctx *gin.Context) {
	var ins model.Book
	id := ctx.Param("isbn")
	if err := h.db.Where("isbn = ?", id).Take(&ins).Error; err != nil {
		response.Failed(ctx, err)
		return
	}
	ctx.JSON(http.StatusOK, ins)
}

// 删除Book
func (h *BookApiHandler) DeleteBook(ctx *gin.Context) {
	id := ctx.Param("isbn")
	if err := h.db.Where("isbn = ?", id).Delete(model.Book{}).Error; err != nil {
		response.Failed(ctx, err)
		return
	}
}

func Registry(r *gin.Engine) {
	// // 配置业务路有, Book类型的资源的 一套简单的CRUD
	// // 创建Book -> Book
	// // POST, Body
	// book := server.Group("/api/books")
	// book.POST("", func(ctx *gin.Context) {
	// 	// 获取Book用户传达的参数
	// 	ins := new(Book)
	// 	if err := ctx.ShouldBindJSON(ins); err != nil {
	// 		Failed(ctx, err)
	// 		return
	// 	}

	// 	// book, save
	// 	if err := db.Save(ins).Error; err != nil {
	// 		Failed(ctx, err)
	// 		return
	// 	}

	// 	ctx.JSON(http.StatusOK, ins)
	// })
	// // 查询Book列表 -> []*Book
	// // SELECT * FROM `books`
	// book.GET("", func(ctx *gin.Context) {
	// 	var books []Book
	// 	if err := db.Find(&books).Error; err != nil {
	// 		Failed(ctx, err)
	// 		return
	// 	}
	// 	ctx.JSON(http.StatusOK, books)
	// })
	// // 查询Book详情
	// book.GET("/:isbn", func(ctx *gin.Context) {
	// 	var ins Book
	// 	id := ctx.Param("isbn")
	// 	if err := db.Where("isbn = ?", id).Take(&ins).Error; err != nil {
	// 		Failed(ctx, fmt.Errorf("Book not found"))
	// 		return
	// 	}
	// 	ctx.JSON(http.StatusOK, ins)
	// })
	// // 更新Book
	// book.PUT("/:isbn", func(ctx *gin.Context) {
	// 	id := ctx.Param("isbn")

	// 	// 获取用户参数, 读取用户的更新参数
	// 	req := BookSpec{}
	// 	if err := ctx.ShouldBindJSON(&req); err != nil {
	// 		Failed(ctx, err)
	// 		return
	// 	}

	// 	// gorm更新是，如果字段为零值 就不更新该字段, is_sale 没办法更新为false
	// 	// 如果越到零值，也需要更新，则需要转化为 指针类型
	// 	if err := db.Where("isbn = ?", id).Model(&Book{}).Updates(req).Error; err != nil {
	// 		Failed(ctx, err)
	// 		return
	// 	}

	// 	// 针对有零值的字段独立更新
	// 	// if err := db.Where("isbn = ?", id).Model(&Book{}).Update("is_sale", req.IsSale).Error; err != nil {
	// 	// 	Failed(ctx, err)
	// 	// 	return
	// 	// }
	// 	// // ......

	// 	// 再次查询出来
	// 	var ins Book
	// 	if err := db.Where("isbn = ?", id).Take(&ins).Error; err != nil {
	// 		Failed(ctx, fmt.Errorf("Book not found"))
	// 		return
	// 	}

	//		// 查询出更新后的数据
	//		ctx.JSON(http.StatusOK, ins)
	//	})
	//
	// // 删除Book
	//
	//	book.DELETE("/:isbn", func(ctx *gin.Context) {
	//		id := ctx.Param("isbn")
	//		if err := db.Where("isbn = ?", id).Delete(&Book{}).Error; err != nil {
	//			Failed(ctx, err)
	//			return
	//		}
	//	})
}
